//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Utils/Base/Common.h"
#include <stl_ext/GL/opengl.h>

//#include <glsl-optimizer-master/src/glsl/glsl_optimizer.h>


namespace Engine
{
namespace Utils
{


	struct ShaderAttrib
	{
		const char *	name;
		int				index;
		int				type;
		///
		ShaderAttrib (int index, const char *name, int type = 0) : index(index), name(name), type(type) {}
	};


	//
	// Shader Utils
	//

	struct ShaderUtils
	{
	// variables
	private:
		//Ptr< glslopt_ctx >	_context;
		void *		_window;
		void *		_renderContext;
		TGLContext	_glContext;
		uint		_version;


	// methods
	public:
		ShaderUtils () : _window(null), _renderContext(null), _version(0)
		{
			//_context = glslopt_initialize( true );
			//_Init();
		}

		~ShaderUtils ()
		{
			//glslopt_cleanup( _context );
			_Destroy();
		}


		bool Optimize (uni_c_string input, string &output)
		{
			/*glslopt_shader *	shader	= glslopt_optimize( _context, kGlslOptShaderVertex, input.cstr(), 0 );
			bool				res		= false;

			if ( glslopt_get_status( shader ) )
			{
				output	= glslopt_get_output( shader );
				res		= true;
			}
			else
			{
				string log = glslopt_get_log( shader );
				LOG( "Shader optimization error:\n" + log, ELog::ERROR_1 );
			}

			glslopt_shader_delete( shader );
			return res;*/
			return true;
		}


		bool GenAttribs (const ShaderAttrib *attribs, int attribsCount,
						 char *str, int &strLen) const
		{
			/*enum {
				GL_FLOAT			= 0x1406,
				GL_FLOAT_VEC2		= 0x8B50,
				GL_FLOAT_VEC3		= 0x8B51,
				GL_FLOAT_VEC4		= 0x8B52,
				GL_FLOAT_MAT2		= 0x8B5A,
				GL_FLOAT_MAT3		= 0x8B5B,
				GL_FLOAT_MAT4		= 0x8B5C,
			};*/

			string	s;

			for (int i = 0; i < attribsCount; ++i)
			{
				ShaderAttrib const &	attr = attribs[i];

				s << "attribute ";

				switch ( attr.type )
				{
					case GL_FLOAT		:	s << "float";	break;
					case GL_FLOAT_VEC2	:	s << "vec2";	break;
					case GL_FLOAT_VEC3	:	s << "vec3";	break;
					case GL_FLOAT_VEC4	:	s << "vec4";	break;
					case GL_FLOAT_MAT2	:	s << "mat2";	break;
					case GL_FLOAT_MAT3	:	s << "mat3";	break;
					case GL_FLOAT_MAT4	:	s << "mat4";	break;
					default				:	WARNING( "unknown attrib type!" );	return false;
				}

				s << ' ' << attr.name << ";\n";
			}

			s << "\n";

			if ( s.Count() >= (uint)strLen )
			{
				WARNING( "output string is too long!" );
				return true;
			}

			strLen = s.Length();
			MemCopy( str, s.ptr(), s.Count() );
			return true;
		}


		bool Validate (const char *fs, const char *vs,
						const ShaderAttrib *attribs, int attribsCount,
						const char ** uniforms, int uniformsCount);

	private:
		bool _Init ();
		void _Destroy ();
		bool _IsInitialized () const;
	};


}	// Utils
}	// Engine